package com.oig.sys.base.service.impl;

import cn.hutool.core.util.StrUtil;
import com.oig.common.constants.CommonEnum;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysPageInfo;
import com.oig.common.module.SysRequest;
import com.oig.sys.base.dao.ITbUnitDao;
import com.oig.sys.base.dto.UnitDto;
import com.oig.sys.base.entity.TbUnit;
import com.oig.sys.base.service.ITbUnitService;
import com.oig.sys.base.vo.UnitVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wuxl
 */
@Slf4j
@Service
public class TbUnitServiceImpl implements ITbUnitService {

	private final ITbUnitDao tbUnitDao;

	@Autowired
	public TbUnitServiceImpl( ITbUnitDao tbUnitDao){
		 this.tbUnitDao = tbUnitDao;
	}

    @Transactional
	@Override
	public UnitVo addUnit(UnitDto unitDto) {
		TbUnit unit = new TbUnit();
		BeanUtils.copyProperties(unitDto,unit);
		unit.setStatus(CommonEnum.CommonStatusEnum.OK.getCode());
		this.tbUnitDao.save(unit);
		UnitVo unitVo = new UnitVo();
		BeanUtils.copyProperties(unit,unitVo);
		return unitVo;
	}

    @Transactional
	@Override
	public UnitVo updateUnit(UnitDto unitDto) {
		TbUnit unit = this.tbUnitDao.getByCode(unitDto.getCode()) ;
		if (unit==null){
			throw new BadRequestException("记录不存在") ;
		}
		BeanUtils.copyProperties(unitDto,unit,"code","status");
		this.tbUnitDao.save(unit);
		UnitVo unitVo = new UnitVo();
		BeanUtils.copyProperties(unit,unitVo);
		return unitVo;
	}

    @Transactional
	@Override
	public void cancelUnit(String code) {
		TbUnit unit = this.tbUnitDao.getByCode(code) ;
		if (unit==null){
			throw new BadRequestException("code错误，记录不存在") ;
		}
		unit.setStatus(CommonEnum.CommonStatusEnum.DEL.getCode());
		this.tbUnitDao.save(unit);
	}


	@Override
	public SysPageInfo<UnitVo> queryList(SysRequest<UnitDto> unitRequest) {
		Pageable pageable = unitRequest.pageable();
		Page<TbUnit> page ;
		if (unitRequest.getParamDto()!=null){
			Specification<TbUnit> specification = new Specification<TbUnit>() {
				@Override
				@Nullable
				public Predicate toPredicate(@NonNull Root<TbUnit> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder criteriaBuilder) {
					List<Predicate> predicateList = new ArrayList<>();
					if (StrUtil.isNotBlank(unitRequest.getParamDto().getName())) {
						Path<String> namePath = root.get("name");
						predicateList.add(criteriaBuilder.like(namePath, "%" + unitRequest.getParamDto().getName() + "%"));
					}
					Path<String> statusPath = root.get("status");
					if (StrUtil.isNotBlank(unitRequest.getParamDto().getStatus())) {
						log.debug("query by status:{}", unitRequest.getParamDto().getStatus());
						predicateList.add(criteriaBuilder.equal(statusPath, unitRequest.getParamDto().getStatus()));
					} else {
						//默认查生效的
						predicateList.add(criteriaBuilder.equal(statusPath, CommonEnum.CommonStatusEnum.OK.getCode()));
					}
					if (StrUtil.isNotBlank(unitRequest.getParamDto().getCode())) {
						Path<String> codePath = root.get("code");
						predicateList.add(criteriaBuilder.equal(codePath, unitRequest.getParamDto().getCode()));
					}
					criteriaQuery.where(predicateList.toArray(new Predicate[0]));
					return criteriaQuery.getRestriction();
				}
			} ;
			page = this.tbUnitDao.findAll(specification, pageable) ;
		} else {
			page = this.tbUnitDao.findAll(pageable);
		}
		List<UnitVo> voList = new ArrayList<>();
		for (TbUnit unit : page.getContent()){
			UnitVo unitVo = new UnitVo();
			BeanUtils.copyProperties(unit,unitVo);
			voList.add(unitVo);
		}
		SysPageInfo<UnitVo> sysPageInfo = new SysPageInfo<>(unitRequest.getPageNo(), unitRequest.getPageSize(), page.getTotalElements());
		sysPageInfo.setList(voList);
		return sysPageInfo;
	}
}
